/*
 * @Author: zlz5v5
 * @LastEditors: zlz
 * @Date: 2019-08-19 11:31:43
 * @LastEditTime: 2019-08-20 10:39:59
 */

/**
 * @description: 软件工程中，我们不仅要创建一致的定义良好的API，同时也要考虑可重用性。
 *               组件不仅能够支持当前的数据类型，同时也能支持未来的数据类型，这在创建大型系统时为你提供了十分灵活的功能。
 * @param {type}
 * @return:
 */

// function generics(params: number): number {
//     console.log(params);
//     return params;
// }

/* 
  解析上面这个函数,因为这是我们一开始定义的函数,所需要的业务逻辑是number的返回值,但是随着业务量的增加
  可能将来的返回值不只是number,所以我们可能会定义any
*/

// function generics(params:any):any {
//     return params;
// }

// 但是这样定义会定义全部的类型
// 因此，我们需要一种方法使返回值的类型与传入参数的类型是相同的。
// 这里，我们使用了 类型变量，它是一种特殊的变量，只用于表示类型而不是值,所以这个时候我们会定义"泛型"

// function generics<T>(params: T): T {
//     return params
// }
// // 使用类型推论定义变量
// // let output = generics<string>('这是一段话')
// // 编辑器会自动识别类型,所以不需要定义类型
// let output = generics('这是一段话')
// console.log(typeof output)

/**
 * 使用泛型创建像identity这样的泛型函数时，编译器要求你在函数体必须正确的使用这个通用的类型。
 * 换句话说，你必须把这些参数当做是任意或所有类型。你所写函数都要符合任意参数逻辑
 */

// function generics<T>(params: T): T {
//     // console.log(params.length)
//     //这样写会报错是因为传进来的可能是没有length的类型参数
//     return params
// }

function generics<T>(params: T[]): T[] {
    console.log(params.length)
    return params
}
